import { fileURLToPath, URL } from 'node:url'
import path from 'path'

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
// import { VantResolver } from 'unplugin-vue-components/resolvers' 此导入方式无法导入showToast
import { VantResolver } from '@vant/auto-import-resolver'
import legacy from '@vitejs/plugin-legacy'
import compressPlugin from 'vite-plugin-compression'
import removeConsole from 'vite-plugin-remove-console'

// https://vite.dev/config/
export default defineConfig(({ mode }) => {
  const { VITE_PROXY_URL, VITE_ENV, VITE_PUBLIC_PATH } = loadEnv(mode, process.cwd())

  return {
    base: VITE_PUBLIC_PATH,
    server: {
      host: true,
      port: 8888,
      proxy: {
        '/api3': {
          target: VITE_PROXY_URL,
          changeOrigin: true,
          // rewrite: (path) => path.replace(/^\/api/, '')
        },
      },
    },
    plugins: [
      vue(),
      vueJsx(),
      vueDevTools(),
      AutoImport({
        // 添加Vant方法API的自动导入
        resolvers: [VantResolver()],
        dts: 'auto-imports.d.ts', // 生成配置文件
        imports: [
          'vue',
          'vue-router',
          'pinia',
          // 显式导入 Vant 的函数式 API 配合unplugin-vue-components/resolvers使用
          // {
          //   vant: ['showToast', 'showDialog', 'showNotify', 'showImagePreview'],
          // },
        ],
        eslintrc: {
          enabled: true, // 默认false, true启用。生成一次就可以，避免每次工程启动都生成，一旦生成配置文件之后，最好把enable关掉，即改成false，否则这个文件每次会在重新加载的时候重新生成，这会导致eslint有时会找不到这个文件。当需要更新配置文件的时候，再重新打开
          filepath: './.eslintrc-auto-import.json',
          globalsPropValue: true,
        },
      }),
      Components({
        resolvers: [VantResolver()],
      }),
      legacy({
        targets: ['ios 11', 'Chrome 64'],
      }),
      compressPlugin({
        verbose: true,
        disable: false,
        threshold: 10240,
        algorithm: 'gzip',
        ext: '.gz',
      }),
      ['prod'].includes(VITE_ENV) && removeConsole(),
    ],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
      },
    },
    define: {
      global: 'globalThis', // 解决浏览器兼容性问题，将 global 定义为 globalThis
      __BASE_ENV__: process.env,
    },
    build: {
      sourcemap: VITE_ENV !== 'prod', // 生产环境不生成 sourcemap，减少包体积
      assetsInlineLimit: 10 * 1024, // 小于此阈值的导入或引用资源将内联为 base64 编码，以避免额外的 http 请求。设置为 0 可以完全禁用此项。 默认 4096(4k)
      chunkSizeWarningLimit: 1024, // chunk 大小警告阈值 默认500
      rollupOptions: {
        output: {
          // 输出文件命名规则，包含 hash 用于缓存控制
          chunkFileNames: 'assets/js/[name]-[hash].js',
          entryFileNames: 'assets/js/[name]-[hash].js',
          assetFileNames: 'assets/[name]-[hash].[ext]',
          // 手动分包策略：将 node_modules 中的包按包名分割
          manualChunks(id) {
            if (id.includes('node_modules') && !id.includes('@sentry')) {
              const parts = id.toString().split('node_modules/')
              // 获取最后一个 node_modules 后的部分
              const lastPart = parts[parts.length - 1]
              return lastPart.split('/')[0].toString()
            }
          },
        },
        external: (id) => {
          // 外部化 Node.js 内置模块，避免在浏览器环境中打包
          // 解决 @web-tracing/vue3 中 worker_threads 等模块的警告
          const nodeBuiltins = [
            'worker_threads', // 工作线程模块
            'fs', // 文件系统模块
            'path', // 路径处理模块
            'os', // 操作系统模块
            'crypto', // 加密模块
            'stream', // 流处理模块
            'util', // 工具模块
            'events', // 事件模块
            'buffer', // 缓冲区模块
            'process', // 进程模块
          ]

          // 检查是否为 Node.js 内置模块（支持 node: 前缀）
          if (nodeBuiltins.some((builtin) => id === builtin || id.startsWith(`node:${builtin}`))) {
            return true
          }

          // 生产环境外部化 vconsole，避免 eval 函数警告
          if (VITE_ENV === 'prod' && id.includes('vconsole')) {
            return true
          }

          return false
        },
      },
    },
  }
})
